package com.yuanfeng.activity.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.yuanfeng.activity.dto.GetAvailableVcBaseDTO;
import com.yuanfeng.activity.dto.UserGetVoucherParamDTO;
import com.yuanfeng.activity.dto.UserVcBaseDTO;
import com.yuanfeng.activity.entity.ActivityRedpacketBaseEntity;
import com.yuanfeng.activity.entity.ActivityVoucherBaseEntity;
import com.yuanfeng.activity.entity.ActivityVoucherTemplateEntity;
import com.yuanfeng.activity.mapper.ActivityRedpacketBaseMapper;
import com.yuanfeng.activity.mapper.ActivityVoucherBaseMapper;
import com.yuanfeng.activity.mapper.ActivityVoucherTemplateMapper;
import com.yuanfeng.activity.service.ActivityVoucherBaseService;
import com.yuanfeng.activity.vo.*;
import com.yuanfeng.commoms.constant.CommonStatusEnum;
import com.yuanfeng.commoms.constant.CommonType;
import com.yuanfeng.commoms.exception.BizCodeEnume;
import com.yuanfeng.commoms.util.ParseTokenUtils;
import com.yuanfeng.commoms.util.RedisLock;
import com.yuanfeng.commoms.util.RedisUtil;
import com.yuanfeng.commoms.util.ResponseResult;
import com.yuanfeng.commoms.util.querypage.PageUtils;
import com.yuanfeng.commoms.util.querypage.Query;
import com.yuanfeng.commoms.vo.activity.VoucherBaseVO;
import com.yuanfeng.commoms.vo.activity.YfVoucherBaseVO;
import com.yuanfeng.commoms.vo.user.UserInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.Jedis;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName ActivityVoucherBaseServiceImpl
 * @Description 代金券表
 * @Author cyp
 * @Date 2023-05-25 16:55:50
 * @Version 1.0
 **/
@Service
public class ActivityVoucherBaseServiceImpl extends ServiceImpl<ActivityVoucherBaseMapper, ActivityVoucherBaseEntity>
        implements ActivityVoucherBaseService {

    @Autowired
    private ActivityRedpacketBaseMapper activityRedpacketBaseMapper;

    @Autowired
    private ActivityVoucherTemplateMapper activityVoucherTemplateMapper;

    @Override
    public ResponseResult selectVoucherTempByShopId(GetAvailableVcBaseDTO param) {
        if(null == param.getToken()){
            return ResponseResult.fail(0, "token为null");
        }
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(param.getToken());

        if(userInfo!=null){
            param.setVoucherOwnerId(userInfo.getUserId());
            param.setCommonId(param.getCommonId());
            List<YfVoucherTemplateVO> yfVoucherTemplates = this.baseMapper.selectVoucherTempByShopId(param);

            if (CollectionUtils.isEmpty(yfVoucherTemplates)) {
                yfVoucherTemplates = Lists.newArrayList();
            }

            if (CollectionUtils.isEmpty(yfVoucherTemplates)) {
                return ResponseResult.fail(0, "该店铺没有代金券");
            }

            // 判断店铺的优惠券该用户是否领取过
            if (StringUtils.isBlank(param.getToken())) {
                return  ResponseResult.fail(0, "未登录状态下查看");
            }
            for (YfVoucherTemplateVO yfVoucherTemplate : yfVoucherTemplates) {
                // 判断代金券是否领取过
                param.setVoucherTId(yfVoucherTemplate.getVoucherTId());
                ActivityVoucherTemplateEntity voucherTemplate = activityVoucherTemplateMapper.selectById(param.getVoucherTId());
                if (null == voucherTemplate) {
                    yfVoucherTemplate.setReceiveOrNot(0);
                }else if (voucherTemplate.getVoucherTGiveout() >= voucherTemplate.getVoucherTTotal()) {
                    yfVoucherTemplate.setReceiveOrNot(1);
                }else {
                    // 判断代金券是否领取过
                    Integer voucherIdCount = this.baseMapper.checkReceivedOrNot(param);
                    if (voucherIdCount != null && voucherTemplate.getVoucherTEachlimit() != 0
                            && voucherIdCount >= voucherTemplate.getVoucherTEachlimit()) {
                        yfVoucherTemplate.setReceiveOrNot(1);
                    }else {
                        yfVoucherTemplate.setReceiveOrNot(0);
                    }
                }
            }
            return ResponseResult.success( yfVoucherTemplates);
        }else{
            return ResponseResult.fail(0, "请先登录");
        }

    }

    @Override
    public VoucherBaseVO getVoucherDetail(Map<String, Object> map) {
        VoucherBaseVO voucherDetail = this.baseMapper.getVoucherDetail(map);

        List<Integer> avaliableGoods = this.baseMapper.selectAvaliableGoods(voucherDetail.getVoucherId());
        voucherDetail.setAvaliableGoods(avaliableGoods);

        return voucherDetail;
    }

    @Override
    public ResponseResult updateSalesPrm(Map<String, Object> paraMap) {
        ObjectMapper objectMapper = new ObjectMapper();
        String redpacketId = (String) paraMap.get("redpacketId");
        String platformVoucherCode = (String) paraMap.get("platformVoucherCode");
        String[] voucherIds2 = objectMapper.convertValue(paraMap.get("voucherId"), String[].class);
        String orderId = null;
        String[] voucherIds = null;
        if (!StringUtils.isEmpty(platformVoucherCode) && !"0".equals(platformVoucherCode)) {
            List<String> voucherIdList = null;
            if (null != voucherIds2) {
                voucherIdList = new ArrayList<>(Arrays.asList(voucherIds2));
            } else {
                voucherIdList = Lists.newArrayList();
            }
            voucherIdList.add(platformVoucherCode);
            voucherIds = new String[voucherIdList.size()];
            voucherIdList.toArray(voucherIds);
        } else {
            voucherIds = voucherIds2;
        }
        // 退款与否1新人下单2退款红包状态修改
        String type = paraMap.get("type") != null ? paraMap.get("type").toString() : null;
        if (type != null) {
            Integer state = type.equals("1") ? 2 : 1;
            orderId = (String) paraMap.get("orderId");
            if (null != redpacketId && !redpacketId.isEmpty()) {
                int redpacketTorf = activityRedpacketBaseMapper.update(null, new LambdaUpdateWrapper<ActivityRedpacketBaseEntity>()
                        .eq(ActivityRedpacketBaseEntity::getRedpacketId, redpacketId)
                        .set(ActivityRedpacketBaseEntity::getRedpacketState, state)
                        .set(null != paraMap.get("orderId") && state == 2, ActivityRedpacketBaseEntity::getRedpacketOrderId, orderId));

                if (redpacketTorf == CommonStatusEnum.FAIL.getCode()) {
                    return ResponseResult.fail(CommonStatusEnum.FAIL.getCode(), CommonStatusEnum.FAIL.getValue());
                }
            }
            //代金券
            if (null != voucherIds) {
                for (String voucherId : voucherIds) {
                    String[] voucherNoList = voucherId.split("-");
                    for (String voucherNo : voucherNoList) {
                        Map<String, Object> voucherMap = new HashMap<>();
                        // 代金券状态(1-未用,2-已用,3-过期,4-收回)',
                        voucherMap.put("voucherState", state);
                        voucherMap.put("voucherId", voucherNo);
                        if (null != paraMap.get("orderId") && state == 2) {
                            voucherMap.put("orderId", orderId);
                        }
                        ResponseResult voucherTorf = updateVoucherDetail(voucherMap);
                        if (voucherTorf.getCode() == CommonStatusEnum.FAIL.getCode()) {
                            return ResponseResult.fail(CommonStatusEnum.FAIL.getCode(),CommonStatusEnum.FAIL.getValue());
                        }
                    }
                }
            }
        }
        return ResponseResult.success();
    }

    @Override
    public ResponseResult selectAvailableVcBase(Map<String, Object> paraMap) {
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(paraMap.get("token").toString());

        Map<String, Object> checkMap = new HashMap<>();
        checkMap.put("voucherOwnerId", userInfo.getUserId());
        checkMap.put("voucherState", "1");
        checkMap.put("voucherShopId", paraMap.get("shopId").toString());
        // 拼接店铺代金券金额
        Double shopOrder = 0.00;
        List<Map<String, Object>> goodsInfo = (List<Map<String, Object>>) paraMap.get("goodsInfo");
        List<Integer> commonList = new ArrayList<>();
        List<YfVoucherBaseVO> goodsVoucherBaseList = new ArrayList<>();
        List<Integer> voucherList = new ArrayList<>();
        for (Map<String, Object> goodInfo : goodsInfo) {
            Integer goodsId = goodInfo.get("goodsId") instanceof Integer ? (Integer) goodInfo.get("goodsId") :
                    Integer.parseInt(goodInfo.get("goodsId").toString());
            Double goodsPrice = goodInfo.get("goodsPrice") instanceof Double ? (Double) goodInfo.get("goodsPrice") :
                    Double.parseDouble(goodInfo.get("goodsPrice").toString());
            Integer goodsNum = goodInfo.get("goodsNum") instanceof Integer ? (Integer) goodInfo.get("goodsNum") :
                    Integer.parseInt(goodInfo.get("goodsNum").toString());
            GoodsIdsQueryResultVO goodsBase = this.baseMapper.selectGoodsIdList(goodsId);
            if(null != goodsBase){
                commonList.add(goodsBase.getCommonId());
            }else {
                return ResponseResult.fail(BizCodeEnume.NO_GOODS);
            }
//            // 代发货商品不可使用代金券
//            if(null!=goodsBase && goodsBase.getDealerGoodsFlag().intValue() == CommonType.dealerGoodsFlag.MALL_ADD.getCode()){
//                return ResponseResult.success("未查询到可以用代金券",new ArrayList<>());
//            }
            Double goodOrder = goodsPrice * goodsNum;
            shopOrder = goodOrder + shopOrder;
            List<YfVoucherBaseVO> goodsVoucherList = this.baseMapper.selectGoodsVcBase(goodsBase.getCommonId(), goodOrder,
                    userInfo.getUserId(), paraMap.get("shopId").toString(),voucherList);
            List<Integer> voucherIdList = goodsVoucherList.stream().map(YfVoucherBaseVO::getVoucherId).collect(Collectors.toList());
            voucherList.addAll(voucherIdList);
            goodsVoucherBaseList.addAll(goodsVoucherList);
        }
        if(!commonList.isEmpty()){
            checkMap.put("commonList", commonList);
        }
        checkMap.put("order", shopOrder == 0.00 ? null : shopOrder.toString());
        checkMap.put("now", "now");
        List<YfVoucherBaseVO> yfVoucherBases = this.baseMapper.selectVcBase(checkMap);
        yfVoucherBases = CollectionUtil.isNotEmpty(yfVoucherBases) ? yfVoucherBases : new ArrayList<>();
        if(CollectionUtil.isNotEmpty(goodsVoucherBaseList)){
            yfVoucherBases.addAll(goodsVoucherBaseList);
        }
        List<YfVoucherBaseVO> voucherBases = new ArrayList<>(yfVoucherBases);
        if (CollectionUtil.isNotEmpty(yfVoucherBases)) {
            List<YfVoucherBaseVO> yfVoucherBaseVOList = new ArrayList<>();
            List<String> commonImageList = new ArrayList<>();
            List<Integer> voucherTIdList = new ArrayList<>();
            List<Integer> commonIds = new ArrayList<>(commonList);
            List<Integer> chooseCommonIds = new ArrayList<>();
            StringBuilder voucherNo = new StringBuilder();
            Integer voucherPrice = 0;
            Double voucherLimit = 0.0;
            int index = 0;
            for (YfVoucherBaseVO yfVoucherBase : voucherBases) {
                yfVoucherBases.get(index).setVoucherNo(yfVoucherBase.getVoucherId().toString());
                List<Integer> list = activityVoucherTemplateMapper.selectGoodsIdByVoucherCommon(yfVoucherBase.getVoucherTId());
                if (yfVoucherBase.getIsShopVoucher() == 1 &&!list.isEmpty() && !new HashSet<>(list).containsAll(commonList)) {
                    yfVoucherBases.remove(yfVoucherBase);
                    continue;
                }
                if(yfVoucherBase.getIsShopVoucher() == 2 && !commonIds.isEmpty()){
                    boolean flag = true;
                    for (Integer commonId : list) {
                        if(chooseCommonIds.contains(commonId)) {
                            flag = false;
                            break;
                        }
                    }
                    for (Integer commonId : commonIds) {
                        if (list.contains(commonId)){
                            chooseCommonIds.add(commonId);
                            commonIds.remove(commonId);
                            break;
                        }
                    }
                    if(flag) {
                        if (voucherNo.length() == 0) {
                            voucherNo.append(yfVoucherBase.getVoucherId());
                        } else {
                            voucherNo.append("-").append(yfVoucherBase.getVoucherId());
                        }
                        commonImageList.add(yfVoucherBase.getCommonImage());
                        voucherTIdList.add(yfVoucherBase.getVoucherTId());
                        yfVoucherBaseVOList.add(yfVoucherBase);
                        voucherPrice = voucherPrice + yfVoucherBase.getVoucherPrice();
                        voucherLimit = voucherLimit + yfVoucherBase.getVoucherLimit();
                    }
                }
                index++;
            }
            if(!yfVoucherBaseVOList.isEmpty() && yfVoucherBaseVOList.size() > 1){
                voucherBases.add(new YfVoucherBaseVO("组合优惠",voucherPrice,voucherLimit,voucherNo,
                        voucherTIdList,yfVoucherBaseVOList,commonImageList));
            }
            sortVoucherList(voucherBases);
        }else {
            return ResponseResult.success("未查询到可以用代金券",new ArrayList<>());
        }
        return ResponseResult.success(voucherBases);
    }

    public void sortVoucherList(List<YfVoucherBaseVO> voucherList) {
        voucherList.sort((vo1, vo2) -> {
            // 根据大小进行排序，这里以某个字段为例（假设是amount字段）
            if (Double.compare(vo1.getVoucherPrice(), vo2.getVoucherPrice()) == 0) {
                return Double.compare(vo1.getVoucherLimit(), vo2.getVoucherLimit());
            } else {
                return Double.compare(vo2.getVoucherPrice(), vo1.getVoucherPrice());
            }
        });
    }

    @Override
    public ResponseResult insertVcBase(UserGetVoucherParamDTO param) {
        // 获取jedis实例
        Jedis jedis = RedisUtil.getJedis();
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(param.getToken());
        RedisLock redisLock = new RedisLock(jedis, "user-vc-" + userInfo.getUserId() + param.getVoucherTId(), 10000);
        try {
            // 用户锁
            if (redisLock.lock()) {
                param.setVoucherOwnerId(userInfo.getUserId());
                UserGetVoucherUpdateParamVO voucherTemplate = this.baseMapper.selectVcTemById(param);
                if (null == voucherTemplate) {
                    return ResponseResult.fail(0, "该代金券不存在");
                }
                if (voucherTemplate.getVoucherTGiveout() >= voucherTemplate.getVoucherTTotal()) {
                    return ResponseResult.fail(0, "该代金券已领取完，看看其他的代金券");
                }
                // 判断代金券是否领取过
                Integer voucherIdCount = this.baseMapper.checkVoucherOrNot(param);
                if (voucherIdCount != null && voucherTemplate.getVoucherTEachlimit() != 0
                        && voucherIdCount >= voucherTemplate.getVoucherTEachlimit()) {
                    return ResponseResult.fail(0, "代金券已领取到达上限");
                }
                // 获取用户信息
                voucherTemplate.setVoucherOwnerId(userInfo.getUserId());
                voucherTemplate.setVoucherOwnerName(userInfo.getUserName());
                voucherTemplate.setVoucherState(1);
                this.baseMapper.insertyfVoucherBase(voucherTemplate);
                this.baseMapper.updateVoucherGiveout(param);
            } else {
                return ResponseResult.fail(0, "代金券领取失败");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            redisLock.unLock();
            jedis.close();
        }
        return ResponseResult.success();
    }

    @Override
    public ResponseResult selectVcBase(UserVcBaseDTO param) {
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(param.getToken());
        if (userInfo == null) {
            return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
        }
        param.setVoucherOwnerId(userInfo.getUserId());
        Page<VoucherBaseVO> page = new Page<>();
        if(param.getPage() != null && param.getLimit() != null) {
            page = new Page<>(param.getPage(), param.getLimit());
        }else{
            page = new Page<>(0,-1);
        }
        IPage<VoucherBaseVO> yfVoucherBases = this.baseMapper.selectVcBaseByShopBase(page, param);
        if (CollectionUtils.isEmpty(yfVoucherBases.getRecords())) {
            return ResponseResult.fail(BizCodeEnume.NO_USABLE_VOUCHERS_FOUND);
        }

        return ResponseResult.success(PageUtils.getPage(yfVoucherBases));
    }

    @Override
    public ResponseResult updateVoucherDetail(Map<String, Object> voucherMap) {

        this.baseMapper.update(null, new LambdaUpdateWrapper<ActivityVoucherBaseEntity>()
                .eq(voucherMap.get("voucherId") != null, ActivityVoucherBaseEntity::getVoucherId, voucherMap.get("voucherId"))
                .set(voucherMap.get("voucherState") != null, ActivityVoucherBaseEntity::getVoucherState, voucherMap.get("voucherState"))
                .set(voucherMap.containsKey("orderId"), ActivityVoucherBaseEntity::getVoucherOrderId, voucherMap.containsKey("orderId") ));
        if (voucherMap.get("voucherState") != null && voucherMap.get("voucherState") == CommonType.redpacketState.USED.getCode()) {
            ActivityVoucherBaseEntity base = this.baseMapper.selectById(Integer.parseInt(voucherMap.get("voucherId").toString()));
            if (base != null) {
                ActivityVoucherTemplateEntity entity=activityVoucherTemplateMapper.selectById(base.getVoucherTId());
                activityVoucherTemplateMapper.update(null, new LambdaUpdateWrapper<ActivityVoucherTemplateEntity>()
                        .set(ActivityVoucherTemplateEntity::getVoucherTUsed,entity.getVoucherTUsed()+1)
                        .eq(ActivityVoucherTemplateEntity::getVoucherTId,entity.getVoucherTId()));
            }
        }
        return ResponseResult.success();
    }

    @Override
    public ResponseResult queryFullReduceVcList(GetAvailableVcBaseDTO param) {

        List<Integer> voucherTIds = this.baseMapper.selectVoucherTIds(param);

        List<YfVoucherTemplateVO> yfVoucherTemplates = null;
        if (!CollectionUtils.isEmpty(voucherTIds)) {
            param.setVoucherTIds(voucherTIds);
            yfVoucherTemplates = activityVoucherTemplateMapper.selectFullReduceVcList(param);
        }

        if (CollectionUtils.isEmpty(yfVoucherTemplates)) {
            return ResponseResult.fail(0, "暂无优惠券可领取");
        }

        if (StringUtils.isNotBlank(param.getToken())) {
            yfVoucherTemplates = setUserReceiveOrNot(param, yfVoucherTemplates);
        }

        return ResponseResult.success(yfVoucherTemplates);

    }
    /**
     * 处理用户领取状态
     *
     * @param param
     * @param yfVoucherTemplates
     * @return
     */
    private List<YfVoucherTemplateVO> setUserReceiveOrNot(GetAvailableVcBaseDTO param,
                                                        List<YfVoucherTemplateVO> yfVoucherTemplates) {

        List<YfVoucherTemplateVO> noUserVouchers = Lists.newArrayList();
        List<YfVoucherTemplateVO> alreadyUserVouchers = Lists.newArrayList();
        // 获取用户信息
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(param.getToken());
        param.setVoucherOwnerId(userInfo.getUserId());

        List<CheckReceivedVcOrNotResultVO> receivedVcList = this.baseMapper.checkReceivedVcOrNot(param);
        if (!CollectionUtils.isEmpty(receivedVcList)) {
            for (YfVoucherTemplateVO yfVoucherTemplate : yfVoucherTemplates) {

                boolean flag = true;
                for (CheckReceivedVcOrNotResultVO receivedVc : receivedVcList) {

                    // 代金券状态(1-未用,2-已用,3-过期,4-收回)'
                    // ReceiveOrNot:// 0未领取1未用2不可领取3已用4过期5回收
                    Integer voucherState = receivedVc.getVoucherState();
                    if (yfVoucherTemplate.getVoucherTId().intValue() == receivedVc.getVoucherTId().intValue()) {
                        flag = false;
                        if (voucherState.intValue() == 1) {
                            voucherState = 1;
                        } else if (voucherState.intValue() == 2) {
                            voucherState = 3;
                        } else if (voucherState.intValue() == 3) {
                            voucherState = 4;
                        } else {
                            voucherState = 5;

                        }

                        yfVoucherTemplate.setReceiveOrNot(voucherState);

                        if (voucherState.intValue() == 1) {
                            noUserVouchers.add(yfVoucherTemplate);
                        } else {
                            alreadyUserVouchers.add(yfVoucherTemplate);
                        }
                        break;
                    }
                }

                if (flag) {
                    noUserVouchers.add(yfVoucherTemplate);
                }
            }
        } else {
            noUserVouchers.addAll(yfVoucherTemplates);
        }
        noUserVouchers.addAll(alreadyUserVouchers);
        return noUserVouchers;
    }

    @Override
    public ResponseResult queryShopVoucherTempPort(Map<String, Object> paraMap) {
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(paraMap.get("token").toString());
        if(null != userInfo){
            paraMap.put("userId",userInfo.getUserId());
        }
        //分页查询数据
        IPage<QueryShopVoucherTempResultVO> page = this.baseMapper.queryShopVoucherTempPort(new Query<QueryShopVoucherTempResultVO>().getPage(paraMap),paraMap);

        return ResponseResult.success(PageUtils.getPage(page));
    }
}
